﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;

using BlueCMS.Core.Data;
using BlueCMS.Core.Data.Query.Clauses;
using BlueCMS.Core.Data.Query.Columns;
using BlueCMS.Core.Data.Query.Conditions;
using BlueCMS.Core.Data.Query.Tables;
using BlueCMS.Core.Providers;

namespace BlueCMS.Core.Data.Query.Generator
{
    public abstract partial class QueryGeneratorBase
    {
        public virtual string ProcessUpdateQuery(UpdateClause update, SetClause set, FromClause from, WhereClause where, Dictionary<string, DbParameter> parameters)
        {
            StringBuilder sb = new StringBuilder();
            GenerateUpdateStatement(update, sb);
            GenerateSetStatement(set, sb, parameters);
            if (from.Tables.Count > 0)
            {
                GenerateFromStatement(from, sb, parameters);
            }
            GenerateWhereStatement(where, sb, parameters);

            return sb.ToString();
        }

        protected virtual void GenerateUpdateStatement(UpdateClause clause, StringBuilder sb)
        {
            sb.Append("UPDATE ");
            GenerateTableName(clause.UpdateTable, sb);
            sb.Append(" ");
        }

        protected virtual void GenerateSetStatement(SetClause clause, StringBuilder sb, Dictionary<string, DbParameter> parameters)
        {
            sb.Append(" SET ");
            foreach (UpdateColumn column in clause.UpdateColumns)
            {
                GenerateColumnName((string)column.NameOrExpression, sb);
                sb.Append(" = ");
                switch (column.Type)
                {
                    case UpdateType.Aggregate:
                        GenerateAggregate((string)column.Value, sb);
                        break;
                    case UpdateType.Column:
                        GenerateColumnName((string)column.Value, sb);
                        break;
                    case UpdateType.Constant:
                        GenerateConstant(column.Value, sb);
                        break;
                    case UpdateType.Parameter:
                        GenerateParameter(column.Value, sb, parameters);
                        break;
                    case UpdateType.SubSelect:
                        GenerateSubSelect((Action<SelectQuery>)column.Value, sb);
                        break;
                }
                sb.Append(", ");
            }
            sb.Remove(sb.Length - 2, 2);
        }
    }
}
